/*
 * @Description: 基本饼图
 * @Author: YoungWind
 * @Date: 2020-09-25 21:07:48
 * @LastEditTime: 2020-09-25 22:07:09
 * @LastEditors: YoungWind
 * @FilePath: \ccd3\src\ccd3\pie\charts\PieChart.js
 */

import BaseChart from '../../BaseChart.js'
export default class PieChart extends BaseChart {
  constructor(id, data) {
    super(id, data);

    this.color = d3.schemeTableau10;
    this.arcs = null;
    this.classificationKey = "classificationKey";
    this.valueKey = "valueKey";
  }

  setClassificationKey(k) {
    this.classificationKey = k;
    return this;
  }

  setValueKey(k) {
    this.valueKey = k;
    return this;
  }

  setInnerRadius(r) {
    this.innerRadius = r;
    return this;
  }

  init() {
    this.initSvg();
    this.initMainGroup();
    this.initPieGroup();
    return this;
  }

  initPieGroup() {
    this.pathGroup = this.mg.append('g')
      .attr("transform", "translate(" + this.innerWidth / 2 + "," + this.innerHeight / 2 + ")")
      .attr("stroke", "white")
    this.textGroup = this.mg.append('g')
      .attr("transform", "translate(" + this.innerWidth / 2 + "," + this.innerHeight / 2 + ")")
      .attr("font-family", "sans-serif")
      .attr("font-size", 12)
      .attr("text-anchor", "middle")
  }

  initZoom() {
    this.svg.call(d3.zoom()
      .on('zoom', this.zoomed)
    )
  }

  render(data) {
    if (data) {
      this.data = data;
    }
    this.renderData();
    this.renderScale();
    this.renderPath();
    this.renderText();
    return this;
  }

  renderData() {
    this.arcs = d3.pie()
      .sort(null)
      .value(d => d.value)(this.data)
  }

  /**
   * @description: 更新渲染线
   * @param {type} 
   * @return {type} 
   */
  renderPath() {
    this.pathGroupElement = this.pathGroup
      .selectAll("path")
      .data(this.arcs)
      .join("path");

    this.pathGroupElement
      .transition()
      .attr("fill", d => this.colorScale(d.data[this.classificationKey]))
      .attr("d", this.arc);

    this.pathGroupElement
      .append("title")
      .text(d => `${d.data[this.classificationKey]}: ${d.data[this.valueKey].toLocaleString()}`);
  }

  /**
   * @description: 更新文本
   * @param {type} 
   * @return {type} 
   */
  renderText() {

    this.textGroupElement = this.textGroup
      .selectAll("text")
      .data(this.arcs)
      .join("text");
    this.textGroupElement
      .call(text => text.filter(d => (d.endAngle - d.startAngle) > 0.25)
        .selectAll("tspan")
        .data(d => {
          return Object.values(d.data).shift();
        })
        .join("tspan")
        .attr("y", "-0.4em")
        .attr("font-weight", "bold")
        .text((d) => {
          return `${d}`
        })
      )
      .call(text => text.filter(d => (d.endAngle - d.startAngle) > 0.25)
        .append("tspan")
        .attr("x", 0)
        .attr("y", "0.7em")
        .attr("fill-opacity", 0.7)
        .text(d => d.data[this.valueKey].toLocaleString()));

    this.textGroupElement.transition()
      .attr("transform", d => `translate(${this.arcLabel().centroid(d)})`)

  }

  /**
   * @description: 更新比例尺
   * @param {type} 
   * @return {type} 
   */
  renderScale() {
    this.colorScale = d3.scaleOrdinal()
      .domain(this.data.map(d => d[this.classificationKey]))
      .range(d3.quantize(t => d3.interpolateSpectral(t * 0.8 + 0.1), this.data.length).reverse())
  }

  arc = (data) => d3.arc()
    .innerRadius((Math.min(this.innerWidth, this.innerHeight) / 2 - 1) * (this.innerRadius))
    .outerRadius(Math.min(this.innerWidth, this.innerHeight) / 2 - 1)(data)

  arcLabel = () => {
    const radius = Math.min(this.innerWidth, this.innerHeight) / 2 * 0.8;
    return d3.arc()
      .innerRadius(radius)
      .outerRadius(radius);
  }

}